import sys

# import serial
import serial.tools.list_ports
import time
import threading
from datetime import datetime

bytesCnt = 0


def choose_port(port_list):
    if len(port_list) > 0:
        for i, comport in enumerate(port_list):
            print('[', i, ']', 'device', comport.device, 'description', comport.description)
    else:
        print('none port! input any key to refresh')
    return len(port_list)


def serial_timeout():
    global bytesCnt
    print('<-', bytesCnt, 'bytes\r\n', end='')
    bytesCnt = 0
    timer.cancel()


# 按装订区域中的绿色按钮以运行脚本。
if __name__ == '__main__':

    port_num = 'r'
    while True:
        global my_ports_list
        if port_num.isdigit() and int(port_num) < len(my_ports_list):
            port_num = int(port_num)
            baudRate = int(input('input baud rate:'))
            recTimeOut = input('input timeout ms(default 100ms):')
            if len(recTimeOut.strip()) == 0 or (int(recTimeOut) < 0):
                recTimeOut = 100
            else:
                recTimeOut = int(recTimeOut)

            my_serial = serial.Serial(my_ports_list[port_num].device, baudRate, timeout=3)
            if my_serial.is_open:
                break
            else:
                port_num = 'r'
        elif not port_num.isdigit():
            my_ports_list = list(serial.tools.list_ports.comports())
            choose_port(my_ports_list)
        port_num = input('input number:')

    timer = threading.Timer(0.001 * recTimeOut, serial_timeout)
    try:
        while True:
            if my_serial.in_waiting:
                data = my_serial.read_all()  # readline() #.decode('utf-8').strip()  # 读取一行数据并解码为字符串
                if len(data) != 0:
                    if bytesCnt == 0:
                        # 打印到毫秒时间戳
                        print('[', datetime.now().strftime('%H:%M:%S.%f')[:-3], ']', end=' ')
                    bytesCnt = bytesCnt + len(data)
                    print(data.decode('utf-8'), end='')  # 打印接收到的数据
                    sys.stdout.flush()
                    if timer.is_alive():
                        timer.cancel()
                        timer = threading.Timer(0.001 * recTimeOut, serial_timeout)
                        timer.start()
                    else:
                        timer = threading.Timer(0.001 * recTimeOut, serial_timeout)
                        timer.start()
                else:
                    time.sleep(0.00001)

    except KeyboardInterrupt:
        print("程序终止")
    finally:
        my_serial.close()  # 关闭串口
